const fs=require('fs/promises');
const chalk=require('chalk');
const {camelCase,upperFirst}=require('lodash');

function getBaseUrl(from,to){
	const froms=from.split('/');
	const tos=to.split('/');
	let cur=0;
	while(froms[cur]===tos[cur]){
		++cur;
	}
	return '../'.repeat(froms.length-cur-1)+tos.slice(cur).join('/');
}
async function checkExtensions(base){
	for(const ext of ['.vue']){
		try{
			const stats=await fs.stat(base+ext);
			if(stats.isFile()){
				return ext;
			}
		}catch{}
	}
	return '';
}
/**
 * 生成指定平台:
 * 		组件style目录下 "主题.scss" 对应的 "主题.ts"
 * 		平台所有主题对应的 "主题.ts" (缺少相关主题的组件, 则用对应default主题的组件)
 */
async function generateTsFile(platform){
	const themes={};
	const components=[];
	const path=`src/components/${platform}`;
	const generatePath=`src/components/generate/${platform}`;
	const dirs=await fs.readdir(path,{withFileTypes:true});
	const types=(await Promise.all(
		dirs.filter((dir) => {
			return dir.isDirectory();
		}).map(async ({name:componentName}) => {
			components.push(componentName);
			const componentPath=`${path}/${componentName}`;
			const type=fs.stat(`${componentPath}/type.ts`).then((stats) => {
				if(stats.isFile()){
					return componentName;
				}
				return '';
			}).catch(() => {
				return '';
			})
			await fs.mkdir(`${generatePath}/${componentName}`,{recursive:true});
			const [ext,themeFileNames]=await Promise.all([
				checkExtensions(`${componentPath}/${componentName}`),
				fs.readdir(`${componentPath}/style`).catch(function(){
					return [];
				}),
			]);
			//region 生成各个主题的组件
			if(themeFileNames.length===0){
				//没有任何主题
				const distFile=`${generatePath}/${componentName}/default.ts`;
				const base=getBaseUrl(distFile,componentPath);
				await fs.writeFile(distFile,[
					`import component from '${base}/${componentName}${ext}';`,
					`export default component;`,
				].join('\r\n'));
			}else{
				//有至少1个主题
				await Promise.all(
					themeFileNames.map((themeFileName) => {
						const theme=themeFileName.slice(0,-5);
						if(themes[theme]==null){
							themes[theme]=new Set();
						}
						themes[theme].add(componentName);
						const distFile=`${generatePath}/${componentName}/${theme}.ts`;
						const base=getBaseUrl(distFile,componentPath);
						return fs.writeFile(distFile,[
							`import '${base}/style/${themeFileName}';`,
							`import component from '${base}/${componentName}${ext}';`,
							`export default component;`,
						].join('\r\n'));
					})
				);
			}
			//endregion
			return type;
		})
	)).filter((type) => type!=='');
	await Promise.all(
		Object.keys(themes).map((theme) => {
			const componentsHasTheme=themes[theme];
			console.log(chalk.blue(`平台: ${platform}, 组件: ${components.length} 个 ===========================`));
			console.log(chalk.magenta(`主题: ${theme}, 组件: ${componentsHasTheme.size} 个`));
			for(const component of Array.from(componentsHasTheme).sort()){
				console.log(chalk.green(`\t${component}组件`));
			}
			return Promise.all([
				fs.writeFile(`${generatePath}/${theme}.ts`,components.map((componentName) => {
					return `export {default as ${componentName}} from './${componentName}/${componentsHasTheme.has(componentName)?theme:'default'}';`;
				}).join('\r\n')),
				fs.writeFile(`exports/${platform}-${theme}.ts`,[
					`import '../src/style/${platform}.scss';`,
					"export * as util from '../src/util';",
					"export * from '../src/locale';",
					"export * as languages from '../src/locale/lang';",
					"export const version=require('../package.json').version;",
					`export * from '../${generatePath}/${theme}';`,
				].join('\r\n')),
			]);
		})
	);
	//region 生成组件类型文件
	await fs.mkdir('exports/types/',{recursive:true});
	await fs.writeFile(`exports/types/${platform}.ts`,
		types.length
		?types.map((component) => {
			return `export * from '../../src/components/${platform}/${component}/type';`;
		}).join('\r\n')
		:'export {};'
	);
	//endregion
	return {
		themes,
		components,
		types,
	};
}
(async () => {
	await Promise.all([
		(async () => {
			const platforms=['pc','app'];
			for(const platform of platforms){
				await generateTsFile(platform);
			}
			const dirs=await fs.readdir('src/util',{withFileTypes:true});
			const typesUtils=(await Promise.all(
				dirs.map(async (dir) => {
					if(dir.isDirectory()){
						try{
							const stats=await fs.stat(`src/util/${dir.name}/type.ts`);
							if(stats.isFile()){
								return dir.name;
							}
						}catch{}
					}
					return '';
				})
			)).filter((type) => type!=='');
			await fs.writeFile('exports/types/base.ts',[
				"export * from '../../src/type';",
				...typesUtils.map((util) => {
					return `export * from '../../src/util/${util}/type';`;
				}),
			].join('\r\n'));
		})(),
		fs.rm('types/export',{force:true,recursive:true}),
	]);
	console.log(chalk.blue('开始生成声明文件'));
})();
